package top.jasonlam.car.utils;

import io.jsonwebtoken.*;
import org.codehaus.jackson.map.ObjectMapper;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.UUID;

/**
 * @author jasonlam
 */
public class JWTUtil {

    //服务器的kye.用户做加解密的key数据

    private static final String JCT_SECRET = "jwt_secret";
    private static final ObjectMapper MAPPER = new ObjectMapper();

    public static SecretKey generalKey() {
        try {
            byte[] encodedKey = JCT_SECRET.getBytes("UTF-8");
            SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
            return key;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 签发JWT，创建token的方法
     *
     * @param id        jwt的唯一标识，主要用来做一次性token。
     * @param iss       jwt签发者
     * @param subject   jwt所面向的用户。一般使用用户的登录名
     * @param ttlMillis 有效期，单位毫秒
     * @return token 是为一个用户的有效登录周期准备的一个tkoen 。用户推出或超时，token失效
     */
    public static String createJWT(String id, String iss, String subject, long ttlMillis) {
        try {
            SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
            long nowMilli = System.currentTimeMillis();
            Date now = new Date(nowMilli);
            SecretKey secretKey = generalKey();
            JwtBuilder builder = Jwts.builder()
                    .setId(id)
                    .setIssuer(iss)
                    .setSubject(subject)
                    //token生成时间
                    .setIssuedAt(now)
                    //设置密匙和算法
                    .signWith(signatureAlgorithm, secretKey);

            if (ttlMillis > 0) {
                long expMillis = nowMilli + ttlMillis;
                Date expDate = new Date(expMillis);
                builder.setExpiration(expDate);
            }
            return builder.compact();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 解析JWT字符串
     *
     * @param jwt 就是生成的token
     * @return
     */
    public static Claims parseJWT(String jwt) {
        SecretKey secretKey = generalKey();
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();
    }

    /**
     * 验证jwt
     *
     * @param jwtStr
     * @return
     */
    public static String validateJWT(String jwtStr) {
        Claims claims = null;
        try {
            claims = parseJWT(jwtStr);
            //成功
        } catch (ExpiredJwtException e) {
            //token过期
            e.printStackTrace();
        } catch (SignatureException e) {
            //签名错误
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String generalSubject(Object subject) {
        try {
            return MAPPER.writeValueAsString(subject);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 使用 ——— 生成token
     * @return
     */
    public static String login(String username) {
        //生成
        String jwtToken = JWTUtil.createJWT(UUID.randomUUID().toString(), "test-jwt", username, 1 * 60 * 1000);
        return jwtToken;
    }


    /**
     * 获取接口放在header中的token
     *
     * @param request
     */
    public void test(HttpServletRequest request) {
        //生成的token
        String token = request.getHeader("Authorization");
        //验证
        String result = JWTUtil.validateJWT(token);
    }


}